package com.rw.coco.handler.message.event;

import com.rw.coco.api.data.CacheMapper;
import com.rw.coco.api.data.CocoDataApi;
import com.rw.coco.api.data.PersistenceMapper;
import com.rw.coco.api.data.model.AccountModel;
import com.rw.coco.api.data.model.BotModel;
import com.rw.coco.api.data.model.CharacterModel;
import com.rw.coco.api.data.persistence.CharacterMapper;
import com.rw.coco.api.event.GroupMessageEvent;
import com.rw.coco.api.event.MessageEvent;
import com.rw.coco.api.event.PrivateMessageEvent;
import com.rw.coco.api.log.CocoLogger;
import com.rw.coco.api.modle.Account;
import com.rw.coco.api.modle.Bot;
import com.rw.coco.api.reply.CocoReplyApi;
import com.rw.coco.service.AccountService;
import com.rw.coco.util.CocoData;
import com.rw.coco.util.config.CocoCommandConfig;
import com.rw.tool.util.string.StringUtil;

/**
 * 可可封装消息对象
 */
public abstract class CocoMessageEvent implements MessageEvent {
    protected final CocoDataApi dataApi;

    protected final CocoLogger logger;

    protected final CocoReplyApi replyApi;

    protected final CocoData cocoData;

    protected final AccountModel accountModel;

    protected final BotModel botModel;

    protected final Account account;

    protected final Bot bot;

    protected final String message;

    protected final boolean hasPrefix;

    protected final String nick;

    /**
     * 获得数据交互API对象
     */
    public CocoDataApi getDataApi() {
        return dataApi;
    }

    /**
     * 获得日志对象
     */
    public CocoLogger getLogger() {
        return logger;
    }

    /**
     * 获得回复API对象
     */
    public CocoReplyApi getReplyApi() {
        return replyApi;
    }

    /**
     * 获取可可的公共数据
     */
    public CocoData getCocoData() {
        return cocoData;
    }

    /**
     * 获得发送者用户模型对象
     */
    public AccountModel getAccountModel() {
        return accountModel;
    }

    /**
     * 获得发送者昵称
     */
    public String getNick() {
        return nick;
    }

    /**
     * 获得机器人模型对象
     */
    public BotModel getBotModel() {
        return botModel;
    }

    public CocoMessageEvent(MessageEvent messageEvent, CocoDataApi dataApi, CocoReplyApi replyApi,
                            CocoLogger logger, CocoData cocoData) {
        this.dataApi = dataApi;
        this.replyApi = replyApi;
        this.logger = logger;
        this.cocoData = cocoData;

        this.account = messageEvent.getSender();
        this.bot = messageEvent.getBot();

        // 获取发送者信息
        Account sender = messageEvent.getSender();
        botModel = dataApi.getPersistenceMapper().getBotMapper().getBotOrDefault(bot.getId());

        // 查找用户
        AccountService accountService = new AccountService(dataApi.getPersistenceMapper());
        accountModel = accountService.getOrDefaultAccount(sender);

        // 获取用户角色卡中的昵称
        CharacterMapper characterMapper = dataApi.getPersistenceMapper().getCharacterMapper();
        CharacterModel character = characterMapper.getCharacter(accountModel.getCharacterId());
        String modelNickname = character == null ? null : character.getNickname();

        // 获取用户的昵称
        String senderNickName = messageEvent.getSender().getNick();
        nick = StringUtil.isEmpty(modelNickname) ? senderNickName : modelNickname;

        // 获取前缀
        CocoCommandConfig cocoCommandConfig = cocoData.getCocoConfig().getCocoCommandConfig();
        String defaultPrefix = cocoCommandConfig.commandProp.get(CocoCommandConfig.DEFAULT_PREFIX);
        String customChar = accountModel.getCustomChar();
        String customPrefix = StringUtil.isEmpty(customChar) ? defaultPrefix : customChar;

        // 解析前缀
        String originalMessage = messageEvent.getMessage().trim();

        // 如果有At开头
        String atMsg = "@" + messageEvent.getBot().getId();
        if (originalMessage.startsWith(atMsg)) {
            originalMessage = originalMessage.substring(atMsg.length()).trim();
        }

        // 去除前缀
        if (StringUtil.startsWith(originalMessage, defaultPrefix)) {
            hasPrefix = true;
            message = originalMessage.substring(defaultPrefix.length()).trim();
        } else if (StringUtil.startsWith(originalMessage, customPrefix)) {
            hasPrefix = true;
            message = originalMessage.substring(customPrefix.length()).trim();
        } else {
            hasPrefix = false;
            message = originalMessage;
        }
    }

    /**
     * 获得原生消息对象
     */
    public abstract MessageEvent getMessageEvent();

    /**
     * 是否是黑名单对象
     */
    public abstract boolean isBlack();

    /**
     * 获得本次事件的机器人
     */
    @Override
    public Bot getBot() {
        return getMessageEvent().getBot();
    }

    /**
     * 获得本次事件的原始消息
     */
    public String getOriginalMessage() {
        return getMessageEvent().getMessage();
    }

    /**
     * 获得本次事件的不带前缀的消息
     */
    @Override
    public String getMessage() {
        return message;
    }

    /**
     * 消息是否带前缀
     */
    public boolean hasPrefix() {
        return hasPrefix;
    }

    /**
     * 获取本次对话的发起人信息
     */
    @Override
    public Account getSender() {
        return getMessageEvent().getSender();
    }

    /**
     * 发回消息
     *
     * @param message 需要发回的消息
     */
    @Override
    public void sendBack(String message) {
        getMessageEvent().sendBack(message);
    }

    /**
     * 对发来消息的人私聊，回复消息
     *
     * @param message 需要发回的消息
     */
    @Override
    public void sendBackSender(String message) {
        getMessageEvent().sendBackSender(message);
    }

    /**
     * 向用户发消息
     *
     * @param message 需要发送的消息
     */
    @Override
    public void sendPrivate(String message, String privateId) {
        getMessageEvent().sendPrivate(message, privateId);
    }


    /**
     * 获得缓存数据交互接口
     */
    public CacheMapper getCacheMapper() {
        return getDataApi().getCacheMapper();
    }

    /**
     * 获得持久化数据交互接口
     */
    public PersistenceMapper getPersistenceMapper() {
        return getDataApi().getPersistenceMapper();
    }

    /**
     * 获得日志交互接口
     */
    public CocoLogger getCocoLogger() {
        return logger;
    }

    /**
     * 静态方法，根据传入的message，创建不同的封装消息对象
     */
    public static CocoMessageEvent of(MessageEvent messageEvent, CocoDataApi dataApi,
                                      CocoReplyApi replyApi, CocoLogger logger, CocoData cocoData) {
        if (messageEvent instanceof GroupMessageEvent) {
            return new CocoGroupMessageEvent((GroupMessageEvent) messageEvent, dataApi, replyApi, logger, cocoData);
        } else if (messageEvent instanceof PrivateMessageEvent) {
            return new CocoPrivateMessageEvent((PrivateMessageEvent) messageEvent, dataApi, replyApi, logger, cocoData);
        } else {
            throw new IllegalArgumentException("Unknown message type!");
        }
    }
}
